package com.alinesno.cloud.initializr.starter.gateway.aop;

import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alinesno.cloud.base.boot.entity.ManagerAccountEntity;
import com.alinesno.cloud.common.core.context.ApplicationContextProvider;
import com.alinesno.cloud.common.facade.pageable.DatatablesPageBean;
import com.alinesno.cloud.rest.gateway.adapter.dto.UserVo;
import com.alinesno.cloud.rest.gateway.adapter.security.CurrentAccountJwt;

/**
 * 数据权限过滤
 * 
 * @author WeiXiaoJin
 * @since 2019年9月15日 下午5:00:19
 */
@Component
@Aspect
public class DataFilterAdvice {

	// 日志记录
	private final static Logger log = LoggerFactory.getLogger(DataFilterAdvice.class);

	@Autowired
	private HttpServletRequest request;

	// 拦截指定的方法,这里指只拦截TestService.getResultData这个方法
	@Pointcut("@annotation(com.alinesno.cloud.initializr.starter.gateway.aop.DataFilter)")
	public void pointcut() {

	}

	// 执行方法前的拦截方法
	@SuppressWarnings("rawtypes")
	@Before("pointcut()")
	public void doBeforeMethod(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException {
		// 获取目标方法的参数信息
		String methodName = joinPoint.getSignature().getName();
		Object[] args = joinPoint.getArgs(); // 请求接收的参数args
		Class<?> targetClass = joinPoint.getTarget().getClass();
		Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
		Method methodClass = targetClass.getMethod(methodName, parameterTypes);

		DataFilter dataFilter = methodClass.getAnnotation(DataFilter.class); // .getAnnotations();
		String beanName = dataFilter.roleBean();

		DataFilterRole type = dataFilter.type();
		log.debug("data filter type :{} , request:{}", type, request);

		for (Object argItem : args) {
			log.debug("argItem:{}", ToStringBuilder.reflectionToString(argItem));

			if (argItem instanceof DatatablesPageBean) { // 分页参数

				DatatablesPageBean page = (DatatablesPageBean) argItem;
				filterDataParams(page, type, beanName);

//        	} else if(argItem instanceof RestWrapper) {
//        		RestWrapper restWrapper = (RestWrapper) argItem ; 
//        		
//        		ManagerAccountEntity account = CurrentAccountSession.get(request) ; 
////        		restWrapper.eq(type.getRoleFiled(), account.getId()) ; 
//        		
//        		argItem = restWrapper ; 
			}
		}

	}

	/**
	 * 添加过滤参数
	 * 
	 * @param page
	 * @param type
	 */
	private void filterDataParams(DatatablesPageBean page, DataFilterRole type, String beanName) {

		// 获取当前用户
		UserVo account = CurrentAccountJwt.getUserVo().getUser();
		Map<String, Object> paramMap = page.getCondition();

		if (type == DataFilterRole.OPERATOR) { // 用户权限

			paramMap.put(type.getRoleFiled(), account.getUserId());

		} else if (type == DataFilterRole.DEPARTMENT) { // 部门权限

			paramMap.put(type.getRoleFiled(), account.getDeptId());

		} else if (type == DataFilterRole.TENANT) { // 租户权限

			paramMap.put(type.getRoleFiled(), account.getTenantId());

		} else if (type == DataFilterRole.APPLICATION) { // 应用权限

			paramMap.put(type.getRoleFiled(), account.getApplicationId());

		} else if (type == DataFilterRole.CUSTOM) { // 自定义权限
			if (beanName != null) {
				try {
					DateFilterParent p = (DateFilterParent) ApplicationContextProvider.getBean(beanName);
					p.filterMap(paramMap, toManagerEntity(account));
				} catch (Exception e) {
					log.error("实例化对象【" + beanName + "】异常:{}", e);
				}
			} else {
				log.warn("自定义数据过滤为空.");
			}
		}

		page.setCondition(paramMap);

	}

	private ManagerAccountEntity toManagerEntity(UserVo account) {
		return null;
	}

}
